\begin{itemize}
	\item{\textbf{Acci\'on:}}
	El objetivo de la funci\'on es dar un aspecto borroso a la imagen original a trav\'es del uso
	de m\'aximos y m\'inimos locales.
	\item{\textbf{Prototipo:}}
	void $normalizar\_local$ (unsigned char* $src$, unsigned char* $dst$, int $h$, int $w$, int $row\_size$)
	\item{\textbf{Procedimiento en C:}}
	A trav\'es del uso de dos ciclos $for$ anidados recorremos cada pixel de la imagen.
	Si este se encuentra en la primer o \'ultima filas o en la primer o \'ultima columnas,
	procedemos a copiar en la imagen destino el pixel original.
	De lo contrario, procedemos a calcular el m\'aximo y m\'inimo locales y calculamos el valor del
	nuevo pixel.
	\\
	\hspace*{10pt} El c\'alculo de m\'aximos y m\'inimos fue realizado en dos m\'etodos aparte, que
	aprovechan la interpretaci\'on de la imagen como un vector para encontrar los pixeles necesarios.
	Si el pixel en cuesti\'on se encuentra en la posici\'on ($i$,$j$) de la imagen, podemos
	encontrarlo en la posici\'on $[i + j*row\_size]$ del vector.
	As\'i, si queremos el valor del pixel "de abajo", alcanza con tomar el valor
	$[i + (j+1)*row\_size]$ del vector, y an\'alogamente para los otros 7 necesarios para la cuenta.	
	\item{\textbf{Procedimiento en ASM:}}
	Dado que para el c\'alculo de m\'aximos y m\'inimos necesitamos los pixeles que rodean al pixel
	en cuesti\'on, la implementaci\'on en $ASM$ de este filtro requiere ciertas consideraciones
	especiales.
	\\ \hspace*{10pt}
	Para ello vamos a contar con dos ciclos anidados, el primero para asegurarnos recorrer todas las
	filas, y el segundo para asegurarnos recorrer todas las columnas. El registro $r12$ nos servir\'a
	para marcar la fila actual, mientras que $r13$ indicar\'a la primera de las columnas a procesar
	en cada iteraci\'on.
	\\ \hspace*{10pt}
	Visto que para procesar un pixel necesitamos los que lo rodean, r\'apidamente nos dimos cuenta
	que ser\'ia imposible procesar 16 pixeles por iteraci\'on dado que esto requerir\'ia leer 18
	pixeles por fila. Es por ello que decidimos procesar 8 pixeles por iteraci\'on, lo que necesita
	leer por lo menos 10 pixeles por fila. Por razones de lenguaje, sin embargo, debemos leer de a
	16, aunque los \'ultimos no los utilizaremos.
	\\ \hspace*{10pt}
	Lo primero que se realiza al entrar a cada iteraci\'on, es guardar en $rbx$ la columna actual
	a partir de la cual vamos a procesar. Luego validamos si nos encontramos en la primer o
	\'ultima filas. En estos casos, dado que los pixeles no deben alterarse, procedemos a copiar
	de forma directa los 16 pixeles leidos a la imagen destino e iterar.
	\\ \hspace*{10pt}
	En caso contrario, podemos garantizarnos el poder leer las filas superiores e inferiores a la
	actual. Esto es importante ya que son fundamentales para el c\'alculo de m\'aximos y m\'inimos.
	Procedemos por lo tanto a guardar en los registros $xmm1$, $xmm2$ (con una copia en $xmm0$) y
	$xmm3$ 16 pixeles de las filas anteriores, actual y siguientes respectivamente a partir de la
	columna actual $rbx$, usando la operaci\'on $movdqu$.
	En caso de tratarse de la primer columna, procedemos a copiar a la imagen destino este primer
	valor antes de seguir con el proceso normal de cada iteraci\'on.
	\\ \hspace*{10pt}
	Dado que estamos trabajando con 8 pixeles por iteraci\'on pero leyendo de a 16, y que la
	\'ultima columna debe copiarse sin alterar, debemos realizar un proceso adicional cuando
	estemos leyendo las \'ultimas 16 columnas de cada fila.
	Este consiste en tratar normalmente los 8 primeros pixeles y luego trabajar sobre los
	\'ultimos 8. Para marcar que este segundo proceso debe realizarse utilizamos el registro $rax$,
	que es limpiado cada vez que pasamos a una nueva fila, adem\'as de guardar una copia de $xmm1$,
	$xmm2$ y $xmm3$ para su posterior uso.
	\\ \hspace*{10pt}
	El proceso normal de las columnas consiste en calcular primero los m\'aximos y m\'inimos para
	luego realizar las divisiones y sumas correspondientes.
	Para calcular los m\'aximos lo primero que hacemos es calcular el m\'aximo vertical a trav\'es
	de la operaci\'on $pmaxub$ para cada columna, es decir, el m\'aximo entre un pixel dado, el de
	la fila superior y el de la fila inferior. Estos m\'aximos son guardados en $xmm1$, y los
	llamaremos $M(j_s)$.
	\\
	\\ \hspace*{50pt}
	$xmm1 = M(0_s)$ $M(1_s)$ $M(2_s)$ $M(3_s)$
	$M(4_s)$ $M(5_s)$ $M(6_s)$ $M(7_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$M(8_s)$ $M(9_s)$ $M(10_s)$ $M(11_s)$
	$M(12_s)$ $M(13_s)$ $M(14_s)$ $M(15_s)$
	\\
	\\ \hspace*{10pt}
	Guardando en $xmm2$ una copia de $xmm1$ shifteada a la derecha, podemos calcular y guardar en
	$xmm1$ los m\'aximos entre dos columnas $M(j_s, j+1_s)$.
	\\
	\\ \hspace*{50pt}
	$xmm1 = M(0_s,1_s)$ $M(1_s,2_s)$ $M(2_s,3_s)$ $M(3_s,4_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$M(4_s,5_s)$ $M(5_s,6_s)$ $M(6_s,7_s)$ $M(7_s,8_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$M(8_s,9_s)$ $M(9_s,10_s)$ $M(10_s,11_s)$ $M(11_s,12_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$M(12_s,13_s)$ $M(13_s,14_s)$ $M(14_s,15s)$ $M(15_s)$
	\\
	\\
	Repitiendo este \'ultimo paso, obtenemos los m\'aximos $M(j_s, j+1_s, j+2_s)$, que son
	equivalentes al $max(i,j)$ deseado.
	\\
	\\ \hspace*{50pt}
	$xmm1 = M(0_s,1_s,2_s)$ $M(1_s,2_s,3_s)$ $M(2_s,3_s,4_s)$ $M(3_s,4_s,5_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$M(4_s,5_s,6_s)$ $M(5_s,6_s,7_s)$ $M(6_s,7_s,8_s)$ $M(7_s,8_s,9_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$M(8_s,9_s,10_s)$ $M(9_s,10_s,11_s)$ $M(10_s,11_s,12_s)$ $M(11_s,12_s,13_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$M(12_s,13_s,14_s)$ $M(13_s,14_s,15_s)$ $M(14_s,15s)$ $M(15_s)$
	\\
	\\
	A trav\'es de un proceso an\'alogo y gracias a la operaci\'on $pminub$, podemos obtener
	los m\'inimos $min(j_s, j+1_s, j+2_s)$, equivalentes a $min(i,j)$.
	\\
	\\ \hspace*{50pt}
	$xmm4 = m(0_s,1_s,2_s)$ $m(1_s,2_s,3_s)$ $m(2_s,3_s,4_s)$ $m(3_s,4_s,5_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$m(4_s,5_s,6_s)$ $m(5_s,6_s,7_s)$ $m(6_s,7_s,8_s)$ $m(7_s,8_s,9_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$m(8_s,9_s,10_s)$ $m(9_s,10_s,11_s)$ $m(10_s,11_s,12_s)$ $m(11_s,12_s,13_s)$
	$\rightarrow$
	\\ \hspace*{95pt}
	$m(12_s,13_s,14_s)$ $m(13_s,14_s,15_s)$ $0$ $0$
	\\
	\\ \hspace*{10pt}
	Una vez que tenemos estos resultados, shifteamos a la derecha un byte usando $psrldq$ el
	registro $xmm0$ para descartar la primer columna que no debemos procesar, y a trav\'es de
	conversiones primero a DW y luego a float usando las operaciones $pmovzxbd$ y $cvtdq2ps$
	respectivamente, pasamos a calcular $\frac{I\_src(i,j)}{max(i,j)}$ para los 8 pixeles
	simultaneamente gracias a $divps$.
	\\ \hspace*{10pt}
	Luego convertimos los valores obtenidos y los m\'inimos a W a trav\'es de las operaciones
	$packusdw$ y $pmovzxbw$ respectivamente, y los sumamos usando $paddw$ para obtener el
	resultado $I\_dst(i,j) = \frac{I\_src(i,j)}{max(i,j)} + min(i,j)$ buscado.
	Finalmente, solo queda guardar estos 8 valores en la imagen destino a trav\'es de la
	operaci\'on $movq$ que guarda solo los 8 bytes inferiores de $xmm0$.
	\\ \hspace*{10pt}
	En caso de tratarse de las \'ultimas columnas, procedemos a realizar un proceso similar al
	descripto anteriormente luego de descartar los primeros 6 (0 a 5) de los 16 pixeles leidos
	originalmente usando $psrldq$.
	Al obtener los 8 pixeles procesados (7 a 14) siguiendo los mismos pasos que anteriormente,
	volvemos a descartar el primer pixel (7) e ingresamos en el octavo lugar el valor de la
	\'ultima columna sin modificar, antes de guardar los 8 pixeles (8 a 15) en la imagen destino.
	A la hora de iterar las columnas, el primer paso es fijarse si acabamos de trabajar con las
	\'ultimas 16 columnas, y en ese caso pasar a iterar las filas.
	De lo contrario, avanzamos 8 columnas, y validamos que queden 16 por leer. De quedar menos,
	comenzamos un ciclo que retrasa de a una columna hasta poder leer 16 columnas, y as\'i
	asegurarnos no leer datos incorrectos ni memoria prohibida.
	\\ \hspace*{10pt}
	La iteraci\'on de las filas consiste simplemente en ver si llegamos a la \'ultima fila, y salir
	de ser as\'i o pasar a la siguiente de lo contrario.
\end{itemize}
